package com.jackrain.nea.wms.service;


import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.util.TypeUtils;
import com.aliyun.openservices.ons.api.Message;
import com.jackrain.nea.config.PropertiesConf;
import com.jackrain.nea.exception.NDSException;
import com.jackrain.nea.fc.dl.api.WmsTranUpdateSaveCmd;
import com.jackrain.nea.util.ApplicationContextHandle;
import com.jackrain.nea.util.ReferenceUtil;
import com.jackrain.nea.util.ValueHolder;
import com.jackrain.nea.web.utils.ObjectToUtil;
import com.jackrain.nea.wms.mapper.WmsSqlMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;

/**
 * 库存调整->FC
 *
 * @author xxs
 * @create 2018/05/26
 */
@Service("com.jackrain.fc.service.WmsTranUpdateService")
@Slf4j
public class WmsTranUpdateService implements BaseProcess {


    @Reference(version = "1", group = "dl")
    private WmsTranUpdateSaveCmd wmsTranUpdateSaveCmd;
    @Autowired
    private WmsSqlMapper wmsSqlMapper;

    @Autowired
    private PropertiesConf pconf;
    private final String TABLE_NAME = "WMS_T_INV_ADJ";
    private final String TABLE_NAME_ITEM = "WMS_T_INV_ADJ_ITEM";
    private static final int STATUS_ING = 00;
    private static final int STATUS_SUCCESS = 99;
    private static final int STATUS_FAILED = 90;

    @Override
    public ValueHolder process(JSONObject paramObject, Message message) throws Exception {


        ValueHolder valueHolder = new ValueHolder();
        if (null == paramObject || paramObject.size() <= 0) {
            return valueHolder;
        }
        //请求处理数据
        List<HashMap> list = (List<HashMap>) paramObject.get("list");
        JSONObject retStr = requestData(list);
        valueHolder.put("retStr", retStr);

        return valueHolder;

    }

    @Override
    public List<HashMap> queryData(int pageSize) {

        WmsTranUpdateService wmsTranUpdateService = ApplicationContextHandle.getBean("com.jackrain.fc.service.WmsTranUpdateService");
        //分页查询数据 先查询未处理的
        String whereStr = " RECIVE_STATUS = 80 ";//00未处理
        String[] fields = new String[]{"ID", "BILL_NO", "WMS_BILL_NO", "BILL_DATE", "ADJ_REASON", "STORE_ECODE", "REMARK", "MODIFIER_ENAME", "MODIFIER_NAME", "RETRY_COUNT", "objid", "state"};
        String order = " WHERE " + whereStr + " ORDER BY ID ASC ";
        String limit = String.valueOf(pageSize);
        List<HashMap> list = wmsSqlMapper.select4(TABLE_NAME, fields, order, limit);
        //未处理的没有再查询失败的
        if (list == null || list.size() <= 0) {

            whereStr = " RECIVE_STATUS = '90'  AND RETRY_COUNT < 5 ";//90失败
            order = " WHERE " + whereStr + " ORDER BY FC_HANDLETIME ASC ";
            list = wmsSqlMapper.select4(TABLE_NAME, fields, order, limit);
//            if (list == null || list.size() <= 0) {
//                return null;
//            }
            //累计重试次数
            // list = hrOrgDeptPostService.reList(list);
        }
        //修改为处理中
        wmsTranUpdateService.batchSave(list, STATUS_ING);
        log.info("WmsTranUpdateService--list-->{}",list);

        return list;

    }

    //查询明细(明细不需要处理)
    private List<HashMap> queryItemData(Long bill_no) {

        JSONObject whereKeys = new JSONObject();
        whereKeys.put("BILL_ID", bill_no);
        String[] fields = new String[]{"SKU", "QTY_BILL"};
        List<HashMap> list = wmsSqlMapper.select(TABLE_NAME_ITEM, fields, whereKeys);
        return list;
    }

    private JSONObject requestData(List<HashMap> list) {

        JSONObject retObject = new JSONObject();
        WmsTranUpdateService wmsTranUpdateService = ApplicationContextHandle.getBean("com.jackrain.fc.service.WmsTranUpdateService");

        if (list == null) {
            return retObject;
        }
//        RecLogUtils.updateCloudTaskLog(taskId, list.size());
        retObject.put("dataCount", list.size());
        //处理数据
        JSONArray postArray = new JSONArray();
        for (int i = 0; i < list.size(); i++) {

            JSONObject fixJo = new JSONObject();
            JSONObject jsonObject = new JSONObject(list.get(i));
            Long bill_id = jsonObject.getLong("ID");
            //查询明细
            try {
                List<HashMap> itemList = queryItemData(bill_id);
                log.info("WmsTranUpdateService--itemList-->{}",itemList);

                if (itemList == null || itemList.size() <= 0) {
                    throw new NDSException("调整单明细为空不处理！");
                }
                JSONArray itemArray = listToJsonarray(itemList);
                fixJo.put("DL_B_INV_ADJ", jsonObject);
                fixJo.put("DL_B_INV_ADJ_ITEM", itemArray);
                postArray.add(fixJo);
            } catch (Exception e) {

                saveWmsErrorDetail(bill_id);
            }

        }
        //同步post
        try {
            JSONObject returnJson = doPost(postArray);
            log.info("WmsTranUpdateService--returnJson-->{}",returnJson);

            retObject.put("ret", returnJson);
            if (returnJson == null || returnJson.size() <= 0) {
                //修改为失败
                wmsTranUpdateService.batchSave(list, STATUS_FAILED);
                throw new NDSException("服务端没有数据，请求参数" + postArray.toJSONString());
            } else {

                Long code = returnJson.getLong("code");
                if (code == null || code != 0) {
                    //再修改为成功
                    JSONArray successArray = returnJson.getJSONArray("success");
                    if (successArray != null && successArray.size() > 0) {
                        wmsTranUpdateService.batchSuccSave(successArray, STATUS_SUCCESS);
                    }
                    JSONArray errorArray = returnJson.getJSONArray("error");
                    wmsTranUpdateService.saveWmsError(errorArray);
                    throw new NDSException("服务端保存出错，" + returnJson);
                }
                if (0 == code) {

                    JSONArray successArray = returnJson.getJSONArray("success");
                    wmsTranUpdateService.batchSuccSave(successArray, STATUS_SUCCESS);
                }
            }
        } catch (Exception e) {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            if ((e instanceof NDSException)) {
                throw e;
            } else {
                //修改为失败
                wmsTranUpdateService.batchSave(list, STATUS_FAILED);
                throw new NDSException(sw.toString());
            }
        }
        return retObject;
    }

    private JSONObject doPost(JSONArray postArrayRow) {

        long startTime = System.currentTimeMillis();
        JSONObject data = new JSONObject();
        data.put("data", postArrayRow);
        ValueHolder result = new ValueHolder();
        try {
            HashMap map = new HashMap(1);
            map.put("param", data);
            Object o = ReferenceUtil.refer(ApplicationContextHandle.getApplicationContext(), "com.jackrain.nea.fc.dl.api.WmsTranUpdateSaveCmd", "dl", "1.0");
            result = ((WmsTranUpdateSaveCmd) o).execute(map);
            if (result == null) {
                result = new ValueHolder();
                result.put("code", -1);
                result.put("error", "服务错误：返回为空");
            }
            if (result.get("code") == null) {
                result.put("code", 0);
            }

        } catch (Exception e) {
            result.put("code", -1);
            if (e instanceof NDSException) {
                result.put("error", "服务错误：" + e.getMessage());
            } else {
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                e.printStackTrace(pw);
                result.put("error", "服务错误：" + sw.toString());
            }
        }
        double spendTime = (double) (System.currentTimeMillis() - startTime) / 1000.0D;
        result.put("doPostSpendTime", spendTime);
        return result.toJSONObject();
//        JSONObject paramJson = new JSONObject();
//        paramJson.put("data", postArrayRow);
//        String erpUrl = pconf.getProperty("port.erp.url", "");
//        erpUrl = erpUrl + "/fc/api/wmsdltranupdate/save";
//        MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
//        map.add("param", JSON.toJSONString(paramJson, SerializerFeature.WriteMapNullValue));
//        String ret = restTemplateService.doPostForm(erpUrl, map);
//
//        Double spendTime = runtimeCompute.endRuntime();
//
//        JSONObject returnJson = JSON.parseObject(ret);
//        returnJson.put("doPostSpendTime", spendTime);
//        returnJson.put("erpUrl", erpUrl);
//
//        return returnJson;

    }

    public void saveWmsErrorDetail(Long bill_id) {

        JSONObject whereKeys = new JSONObject();
        whereKeys.put("id", bill_id);
        int retryCount = retryCount(bill_id);
        JSONObject setKeys = new JSONObject();
        setKeys.put("error_log", "明细不能为空！");
        setKeys.put("recive_status", STATUS_FAILED);//失败
        setKeys.put("fc_handletime", new Timestamp(System.currentTimeMillis()));//处理时间
        setKeys.put("retry_count", retryCount + 1);
        wmsSqlMapper.update(TABLE_NAME, setKeys, whereKeys);
    }

    public void batchSave(List<HashMap> list, int status) {

        if (list == null) {
            return;
        }
        for (int i = 0; i < list.size(); i++) {
            JSONObject jsonObject = new JSONObject(list.get(i));
            if (jsonObject == null) {
                continue;
            }
            Long bill_no = jsonObject.getLong("ID");
            if (ObjectToUtil.isNullOREmpty(String.valueOf(bill_no))) {
                continue;
            }
            JSONObject setKeys = new JSONObject();
            setKeys.put("RECIVE_STATUS", status);//
            setKeys.put("FC_HANDLETIME", new Timestamp(System.currentTimeMillis()));//处理时间
            if (STATUS_SUCCESS == status) {
                setKeys.put("ERROR_LOG", "");//
            }
            if (STATUS_FAILED == status) {
                int retrycount = retryCount(bill_no);
                setKeys.put("RETRY_COUNT", retrycount + 1);
            }
            JSONObject whereKeys = new JSONObject();
            whereKeys.put("ID", bill_no);
            wmsSqlMapper.update(TABLE_NAME, setKeys, whereKeys);
        }
    }
    /**
     * 状态为失败时调用累计重试次数
     */
    private int retryCount(Long bill_no) {

        JSONObject whereKeys = new JSONObject();
        whereKeys.put("ID", bill_no);
        List<HashMap> retryList = wmsSqlMapper.select(TABLE_NAME, new String[]{"RETRY_COUNT"}, whereKeys);
        HashMap hashMap = retryList.get(0);
        int retrycount = TypeUtils.castToInt(hashMap.get("RETRY_COUNT"));
        return retrycount;
    }

    public void batchSuccSave(JSONArray dataArray, int status) {

        if (dataArray == null) {
            return;
        }
        //修改状态
        for (int i = 0; i < dataArray.size(); i++) {

            JSONObject dataJO = dataArray.getJSONObject(i);
            Long bill_no = dataJO.getLong("id");
            Long objid = dataJO.getLong("objid");
            int state = dataJO.getInteger("state");
            if (ObjectToUtil.isNullOREmpty(String.valueOf(bill_no))) {
                continue;
            }
            JSONObject setKeys = new JSONObject();
            setKeys.put("RECIVE_STATUS", status);//
            setKeys.put("objid", objid);
            setKeys.put("state", state);
            setKeys.put("FC_HANDLETIME", new Timestamp(System.currentTimeMillis()));//处理时间
            if (STATUS_SUCCESS == status) {
                setKeys.put("ERROR_LOG", "");//
            }
            JSONObject whereKeys = new JSONObject();
            whereKeys.put("ID", bill_no);
            wmsSqlMapper.update(TABLE_NAME, setKeys, whereKeys);
        }
    }

    public void saveWmsError(JSONArray errorArray) {

        if (errorArray == null) {
            return;
        }
        for (int i = 0; i < errorArray.size(); i++) {
            JSONObject errorObject = errorArray.getJSONObject(i);
            if (errorObject == null) {
                continue;
            }
            Long bill_no = errorObject.getLong("id");
            Long objid = errorObject.getLong("objid");
            int state = errorObject.getInteger("state");

            if (ObjectToUtil.isNullOREmpty(String.valueOf(bill_no))) {
                continue;
            }
            JSONObject whereKeys = new JSONObject();
            whereKeys.put("id", bill_no);
            int retryCount = retryCount(bill_no);
            String msg = errorObject.getString("message");
            JSONObject setKeys = new JSONObject();
            if (!ObjectToUtil.isNullOREmpty(msg)) {
                setKeys.put("error_log", msg);//
            }
            setKeys.put("recive_status", STATUS_FAILED);//失败
            setKeys.put("FC_HANDLETIME", new Timestamp(System.currentTimeMillis()));//处理时间
            setKeys.put("retry_count", retryCount + 1);
            setKeys.put("objid", objid);
            setKeys.put("state", state);
            wmsSqlMapper.update(TABLE_NAME, setKeys, whereKeys);

        }
    }

    private void handleTimeOut(long timeMillis) {

        //修改状态为失败
        JSONObject setKeys = new JSONObject();
        setKeys.put("RECIVE_STATUS", STATUS_FAILED);//
        setKeys.put("FC_HANDLETIME", new Timestamp(System.currentTimeMillis()));//处理时间
        String whereStr = "RECIVE_STATUS = '" + STATUS_ING + "' AND FC_HANDLETIME < '" + new Timestamp(System.currentTimeMillis() - timeMillis) + "'";
        wmsSqlMapper.update3(TABLE_NAME, setKeys, whereStr);
    }

    /**
     * list转jsonarray
     *
     * @param mapList
     * @return jsonArray
     */
    public JSONArray listToJsonarray(List<HashMap> mapList) {

        JSONArray jsonArray = new JSONArray();
        for (int i = 0; i < mapList.size(); i++) {
            HashMap map = (HashMap) mapList.get(i);
            JSONObject jsonObject = new JSONObject(map);
            JSONObject param = JSON.parseObject(JSON.toJSONStringWithDateFormat(jsonObject, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteMapNullValue), Feature.OrderedField);
            jsonArray.add(param);
        }
        return jsonArray;
    }

}
